Custom colour scales for {ggplot2}

R Ladies Cambridge

My R Journey (so far…)

A lollipop chart with each point showing a different stage of the author's career.

What do I do at Jumping Rivers?

Consultancy Hex stickers for four R packages - dplyr, ggplot2, tibble, and readr.

Training Cartoon of a teacher at the front of a class with a board showing an R.

R Community Shiny in Production conference logo of a robot holding a spanner with its left hand. The hex sticker for the Shiny R package is shown on front of the robot.

Start with the default colour scheme…

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() 

Let’s change to a nicer palette…

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_brewer(palette = "Dark2")

See {paletteer} for a collection of colour palette scales.

But that doesn’t match our branding…

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_manual(
    values = c("#4C1E4F",
               "#7D70BA",
               "#D35269")
    )

Now we want to re-use these colours…

…so let’s make a function!

First, let’s define our colours in a list:

my_colours = list(
  my_favourite_colours = c("#4C1E4F", "#7D70BA", "#D35269")
)

Turn colours into a palette

my_palettes = function(palette_name,
                       n,
                       type = c("discrete", "continuous")) {
  palette = my_colours[[palette_name]]
  if (missing(n)) {
    n = length(palette)
  }
  type = match.arg(type)
  out = switch(type,
               continuous = grDevices::colorRampPalette(palette)(n),
               discrete = palette[1:n]
  )
  structure(out, palette_name = palette_name, class = "palette")
}

Make some scale functions

Discrete scales

scale_colour_mycols_d = function(palette_name, ...) {
  ggplot2::scale_colour_manual(
    values = my_palettes(palette_name, type = "discrete"), ...)
}

scale_fill_mycols_d = function(palette_name, ...) {
  ggplot2::scale_fill_manual(
    values = my_palettes(palette_name, type = "discrete"), ...)
}

Make some scale functions

Continuous scales

scale_colour_mycols_c = function(palette_name, ...) {
  ggplot2::scale_colour_gradientn(
    colours = my_palettes(palette_name, type = "continuous"), ...)
}

scale_fill_mycols_c = function(palette_name, ...) {
  ggplot2::scale_fill_gradientn(
    colours = my_palettes(palette_name, type = "continuous"), ...)
}

Use colour or color

scale_color_mycols_d <- scale_colour_mycols_d
scale_color_mycols_c <- scale_colour_mycols_c

See it in action

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = name)) +
  geom_col() +
  scale_fill_mycols_d("my_favourite_colours")

See it in action

ggplot(lemurs, 
       aes(x = name,
           y = n,
           fill = n)) +
  geom_col() +
  scale_fill_mycols_c("my_favourite_colours", 
                      limits = c(0, 12500),
                      breaks = c(0, 12500))

What to do next?

Slides

Questions?